<?php
// +----------------------------------------------------------------------
// | RXThinkCMF_EVTP5.1_PRO前后端分离旗舰版框架 [ RXThinkCMF ]
// +----------------------------------------------------------------------
// | 版权所有 2018~2021 南京RXThinkCMF研发中心
// +----------------------------------------------------------------------
// | 官方网站: http://www.rxthink.cn
// +----------------------------------------------------------------------
// | 作者: ZhangXuanNeng <rxthinkcmf@163.com>
// +----------------------------------------------------------------------
// | 免责声明:
// | 本软件框架禁止任何单位和个人用于任何违法、侵害他人合法利益等恶意的行为，禁止用于任何违
// | 反我国法律法规的一切平台研发，任何单位和个人使用本软件框架用于产品研发而产生的任何意外
// | 、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、附带
// | 或衍生的损失等)，本团队不承担任何法律责任。本软件框架只能用于公司和个人内部的法律所允
// | 许的合法合规的软件产品研发，详细声明内容请阅读《框架免责声明》附件；
// +----------------------------------------------------------------------

namespace app\admin\controller;
use app\admin\service\UploadService;
use app\qsapi\service\BaseService;
use think\response\Json;

/**
 * 上传文件-控制器
 * @author ZhangXuanNeng
 * @since 2020/11/20
 * Class Upload
 * @package app\admin\controller
 */
class Upload extends Backend
{
    /**
     * 上传图片（支持多图片上传）
     * 备注：1、单文件：file
     *      2、多文件：file[],file[]
     * @return array
     * @since 2020/11/20
     * @author ZhangXuanNeng
     */
    public function uploadImage()
    {
        // 错误提示语
        $error = "";
        // 上传图片
        $result = upload_image('file', '', $error);
        if (!$result) {
            return message($error, false);
        }
        // 多图片上传处理
        $list = [];
        if (is_array($result)) {
            foreach ($result as $val) {
                $list[] = IMG_URL . $val;
            }
        } else {
            $list = IMG_URL . $result;
        }
        return $this->jsonReturn(message("上传成功", true, $list));
    }

    /**
     * 上传文件(支持多文件上传)
     * 备注：1、单文件：file
     *      2、多文件：file[],file[]
     *
     * @return array
     * @since 2020/11/20
     * @author ZhangXuanNeng
     */
    public function uploadFile()
    {
        $error = "";
        $dir = '';
        $sdk_version = '';
        if(isset($_GET['sdk_version'])){
            $sdk_version = $_GET['sdk_version'];
        }
        if($sdk_version == 1){
            $dir = 'an';
        }
        if($sdk_version == 2){
            $dir = 'ios';
        }
        if($sdk_version == 4){
            $dir = 'pc';
        }
        if($sdk_version == 'origin'){
            $dir = 'origin';
        }
        // 上传文件(非图片)
        $result = upload_file('file', $dir, $error);
        if (!$result) {
            return message($error);
        }
        return $this->jsonReturn(message("上传成功", true, $result));
    }
    /**
     * 上传图片到oss
     * @return array|void
     */
    public function uploadImageOss(){
        $error = "";
        // 上传文件(非图片)
        $result = upload_image_new('file', '', $error);
        if (!$result) {
            return message($error);
        }
        $src = UPLOAD_TEMP_PATH . '/' . $result['name'];
        $res = BaseService::upload_file_tencent_cos($src,'admin');
        $image = $res['data']['url'];
        $this->jsonReturn(message("上传成功", true, $image));
    }

    /**
     * Desc : 直传文件到oss
     * User : Steven
     * Date : 2024-09-14 13:16
     * @return Json|void
     */
    public function uploadImageOssOld()
    {
        $file = $_FILES['file'] ?? null;
        // 上传验证参数
        $config = [
            // 限制上传最大值MAX=200MB
            'size' => 1024 * 1024 * 200,
            // 限制上传文件后缀
            'ext' => ['jpg','gif','png','bmp','jpeg','JPG','zip','7z'],
            // 限制上传视频文件后缀
            'media_ext' => ['mp4','avi','mkv','mov','rmvb','rm','3gp','mov','flv','wmv','mpeg','mpg','webm']
        ];
        $size = $file['size'] ?? 0;
        if($size > $config['size']) return json(message('上传文件过大',false));
        $name = $file['name'] ?? '';
        $fileExtension = strtolower(pathinfo($name, PATHINFO_EXTENSION));
        $ext = in_array($fileExtension,$config['ext']);
        $media_ext = in_array($fileExtension,$config['media_ext']);

        if(!$ext && !$media_ext) return json(message('上传文件格式不正确',false));
        $tmp_name = $file['tmp_name'] ?? '';
        if(empty($tmp_name) || empty($name)) return json(message('上传失败',false));
        if($media_ext) {
            $file_dir = 'qnboxVideo';
            $name = '/'.md5(time().rand(10000,99999).uniqid()).'.'.$fileExtension;
            $return_dir = 'qnboxVideo_imm';
        }else{
            $file_dir = 'qnbox';
            $name = '/'.date("Ymd").'/'.md5(time().rand(10000,99999).uniqid()).'.'.$fileExtension;
        }

//        $ossUrl = upload_file_2_oss_new_storage($tmp_name,$name,$file_dir);
        $ossUrl = $result = upload_image_new('file', '', $error);
        if(!$ossUrl['status']){
            return json(message('上传失败',false));
        }
        if($ossUrl['data'] && isset($return_dir) && !empty($return_dir)){
            $ossUrl['data'] = str_replace('qnboxVideo', 'qnboxVideo_imm', $ossUrl['data']);
        }

        $this->jsonReturn(message("上传成功", true, $ossUrl['data']));
    }


    public function uploadGameBannerImageOss(){
        $error = "";
        // 上传文件(非图片)
        $result = upload_image_new('file', '', $error);
        if (!$result) {
            return message($error);
        }
        $ext = $result['ext'];
        $ossUrl = upload_file_2_oss($result['file_dir'],$result['name'],'qnbox');
        if(!$ossUrl['status']){
            return message($ossUrl['msg']);
        }
        $img = '';
        if(in_array($ext,['mp4'])){
            $img =  $ossUrl['data']."?x-oss-process=video/snapshot,t_1000,m_fast";
        }
        $this->jsonReturn(message("上传成功", true, ['data' =>$ossUrl['data'],'type' => $ext,'img'=>$img]));
    }


    /**
     * 分片上传
     * @return mixed
     */
    public function zoneUpload()
    {
        $data = $this->request->post();
        $res = $this->zoneUploadMerge($data, $_FILES['file']);
        $this->jsonReturn($res);
    }

    /**
     * 分片上传
     * @param $data
     * @param $file
     * @return mixed
     */
    public function zoneUploadMerge($data, $file)
    {
        $public_dir = app()->getRootPath() . 'public';
        $sdk_version = 0;
        if(isset($_GET['sdk_version'])){
            $sdk_version = $_GET['sdk_version'];
        }
        $dir_name = 'an';
        if($sdk_version == 1){
            $dir_name = 'an';
        }
        if($sdk_version == 2){
            $dir_name = 'ios';
        }
        if($sdk_version == 4){
            $dir_name = 'pc';
        }
        if($sdk_version == 'origin'){
            $dir_name = 'origin';
        }
        $dir = '/uploads/'.$dir_name.'/' . date('Y-m-d');
        $all_dir = $public_dir . $dir;
        if (!is_dir($all_dir)) mkdir($all_dir, 0777, true);
        $filename = $all_dir . '/' . $data['filename'] . '__' . $data['chunkNumber'];
        move_uploaded_file($file['tmp_name'], $filename);
        $res['code'] = 0;
        $res['msg'] = 'error';
        $res['file_path'] = '';
        $res['file_name'] = '';
        if ($data['chunkNumber'] == $data['totalChunks']) {
            @unlink($all_dir . '/' . $data['filename']);
            $filepath = $all_dir . '/' . $data['filename'];
            $out = @fopen($filepath, 'wa');
            for ($i = 1; $i <= $data['totalChunks']; $i++) {
                $inUrl = $all_dir . '/' . $data['filename'] . '__' . $i;
                $in = @fopen($inUrl, "r");
                $str = @fread($in, filesize($inUrl));
                fwrite($out, $str);
                @fclose($in);
                @unlink($inUrl);
            }
            fclose($out);
            if (file_exists($all_dir . '/' . $data['filename'])) {
                $res['code'] = 2;
                $res['msg'] = 'success';
                $res['file_path'] = $dir . '/' . $data['filename'];
                $res['file_name'] = $data['filename'];
                if($sdk_version == 1){
                    sleep(1);
                    $signInfo = getApkSign(\Env::get('root_path') . 'public'.$dir . '/' . $data['filename']);
                    if($signInfo == 'V1' || !$signInfo){
                        $res['code'] = -1;
                        $res['msg'] = '当前版本'.$signInfo.'--请上传V2版';
                        $res['file_path'] = '';
                        $res['file_name'] = '';
                        @unlink( \Env::get('root_path') . 'public'.$dir . '/' . $data['filename']);
                        return $res;
                    }
                }
            }
        } else {
            if (file_exists($all_dir . '/' . $data['filename'] . '__' . $data['chunkNumber'])) {
                $res['code'] = 1;
                $res['msg'] = 'waiting';
                $res['file_path'] = '';
                $res['file_name'] = '';
            }
        }
        return $res;
    }

    public function uploadPcGamePackageNew()
    {
        $data = $this->request->post();
        $result = $this->zoneUploadMerge($data, $_FILES['file']);
        if($result['code'] == 2){
            $file_path = explode('/',$result['file_path']);
            $file_name = array_pop($file_path);
            $file_path = PUBLIC_PATH.'/'.implode('/',$file_path).'/';
            $ossUrl = upload_file_2_oss_new($file_path,$file_name,'PcGamePack/');
            if(!$ossUrl['status']){
                $this->jsonReturn(message('上传失败',false));
            }
            $file_name = explode('/',$ossUrl['data']);
            $file_name = array_pop($file_name);
            $result = [
                'code' => $result['code'],
                'msg' => $result['msg'],
                'file_path' => $ossUrl['data'],
                'file_name' => $file_name
            ];
            $this->jsonReturn($result);
        }
        $this->jsonReturn($result);
    }

    public function uploadPcGamePackage()
    {
        $data = $this->request->post();
        $result = $this->zoneUploadMergeNew($data, $_FILES['file']);
        $this->jsonReturn($result);
    }

    /**
     * Desc : zoneUploadMergeNew
     * User : Steven
     * Date : 2024-08-16 14:14
     * @param $data
     * @param $file
     * @return array
     */
    public function zoneUploadMergeNew($data, $file): array
    {
        $public_dir = app()->getRootPath() . 'public';
        $sdk_version = 0;
        if(isset($_GET['sdk_version'])){
            $sdk_version = $_GET['sdk_version'];
        }
        $dir_name = 'an';
        if($sdk_version == 1){
            $dir_name = 'an';
        }
        if($sdk_version == 2){
            $dir_name = 'ios';
        }
        if($sdk_version == 4){
            $dir_name = 'boxpc';
        }
        if($sdk_version == 'origin'){
            $dir_name = 'origin';
        }
        $dir = '/uploads/'.$dir_name.'/' . date('Y-m-d');
        $all_dir = $public_dir . $dir;

        $res['code'] = 0;
        $res['msg'] = 'error';
        $res['file_path'] = '';
        $res['file_name'] = '';
        if ($data['chunkNumber'] > $data['totalChunks']) {
            $service = new UploadService();
            $_data = [];
            $_data['file_name'] = $data['filename'];
            $_res = $service->getDataRedis($_data);
            if($_res){
                $res['code'] = 1;
                $res['msg'] = 'waiting';
                $res['file_path'] = $dir . '/' . $data['filename'];
                $res['file_name'] = $data['filename'];
                $rData = json_decode($_res, true);
                if($rData['code']==1){
                    $res['code'] = 2;
                    $res['msg'] = '文件上传成功!';
                    $res['file_path'] = $rData['real_file_path'];
                    $res['file_name'] = $rData['file_name'];
                    $res['decompression_size'] = $rData['decompression_size'] ?? '';
                    $service->delDataRedis($_data);
                }
                return $res;
            }
            @unlink($all_dir . '/' . $data['filename']);
            $filepath = $all_dir . '/' . $data['filename'];
            $out = @fopen($filepath, 'wa');
            for ($i = 1; $i <= $data['totalChunks']; $i++) {
                $inUrl = $all_dir . '/' . $data['filename'] . '__' . $i;
                $in = @fopen($inUrl, "r");
                $str = @fread($in, filesize($inUrl));
                fwrite($out, $str);
                @fclose($in);
                @unlink($inUrl);
            }
            fclose($out);
            if (file_exists($all_dir . '/' . $data['filename'])) {
                $res['code'] = 1;
                $res['msg'] = 'waiting';
                $res['file_path'] = $dir . '/' . $data['filename'];
                $res['file_name'] = $data['filename'];
                $_data = [];
                $_data['file_name'] = $data['filename'];
                $_data['real_file_path'] = PUBLIC_PATH.$dir.'/';
                $_data['dir'] = 'PcGamePack/';
                $_data['decompression_size'] = $this->decompressionAfterSize($res['file_path']) ?? '';
                // write_log('INFO', '', '文件:'.json_encode($_data), 'boxpc_pc_upload_merge_new', true);
                $service->setDataRedis($_data);

            }

        } else {
            if ($data['chunkNumber'] <= $data['totalChunks']) {
                if (!is_dir($all_dir)) mkdir($all_dir, 0777, true);
                $filename = $all_dir . '/' . $data['filename'] . '__' . $data['chunkNumber'];
                move_uploaded_file($file['tmp_name'], $filename);
            }
            if (file_exists($all_dir . '/' . $data['filename'] . '__' . $data['chunkNumber'])) {
                $res['code'] = 1;
                $res['msg'] = 'waiting';
                $res['file_path'] = '';
                $res['file_name'] = '';
            }
        }
        return $res;
    }

    /*
     * 解压后文件大小
     */
    public function decompressionAfterSize($file_path): string
    {
        // $command = '/var/tmp/7zzs';
        $command = env('local.7zz_path');
        $file_path = app()->getRootPath() . 'public' . $file_path;
        $output = [];
        exec( "{$command} l {$file_path}",$output,$result);
        $lastLine = end($output);
        preg_match('/\s+(\d+)\s+(\d+)\s+/', $lastLine, $matches);

        $totalOriginalSize = 0;
        $compressedSize    = 0;
        if (isset($matches[1]) && isset($matches[2])) {
            $totalOriginalSize = $matches[1];
            $compressedSize = $matches[2];
        }
        $mb = $totalOriginalSize / (1024 * 1024);
        $mb =  number_format($mb, 2);
        return  $mb ?? 0.00;
    }

}
